home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / arith / iplace.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  9.1 KB  |  425 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  iplace.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. /*              iplace.c           RD, 24.09.91     */
  16. /*     Dies ersetzt irv.c!                */
  17.  
  18. #include <LEDA/impl/iint.h>
  19. #include <LEDA/impl/iloc.h>
  20.  
  21. #ifdef USE_DOUBLEPLACE
  22.  
  23. #ifdef __GNUC__
  24. PLACE PLACEadd(PLACE a, PLACE b, PLACE carry, PLACE *sum)
  25. #else
  26. PLACE PLACEadd(a, b, carry, sum)
  27.     PLACE a, b, carry, *sum;
  28. #endif
  29.     /* *sum=a+b+carry, return Uebertrag */
  30. {    register DOUBLEPLACE accu = 0;
  31.         accu = a;
  32.         accu += b;
  33.         accu += carry;
  34.         *sum = accu;
  35.         return accu >> LOGPLACE;
  36. }
  37.  
  38. #ifdef __GNUC__
  39. PLACE PLACEsub(PLACE a, PLACE b, PLACE carry, PLACE *diff)
  40. #else
  41. PLACE PLACEsub(a, b, carry, diff)
  42.         PLACE a, b, carry, *diff;
  43. #endif
  44.     /* *diff=a-b-carry, return Uebertrag 0 oder 1 */
  45. {       register DOUBLEPLACE accu = 0;
  46.         accu = a;
  47.         accu -= b;
  48.         accu -= carry;
  49.         *diff = accu;
  50.         accu >>= LOGPLACE;
  51.         return accu & 1;
  52. }
  53.  
  54. #ifdef __GNUC__
  55. PLACE PLACEmuladd(PLACE a, PLACE b, PLACE carry, PLACE *paccu)
  56. #else
  57. PLACE PLACEmuladd(a, b, carry, paccu)
  58.     PLACE a, b, carry, *paccu;
  59. #endif
  60.     /* *paccu=*paccu+a*b+carry, return Uebertrag */
  61. {       register DOUBLEPLACE accu = 0;
  62.         accu = a;
  63.         accu *= b;
  64.         accu += *paccu;
  65.         accu += carry;
  66.         *paccu = accu;
  67.         return accu >> LOGPLACE;
  68. }
  69.  
  70. #ifndef __PARC__
  71. #ifdef __GNUC__
  72. PLACE PLACEmul(PLACE a, PLACE b, PLACE carry, PLACE *paccu)
  73. #else
  74. PLACE PLACEmul(a, b, carry, paccu)
  75.         PLACE a, b, carry, *paccu; 
  76. #endif
  77.     /* *paccu=a*b+carry, return Uebertrag */
  78. {       register DOUBLEPLACE accu = 0;
  79.         accu = a;
  80.         accu *= b;
  81.         accu += carry;
  82.         *paccu = accu;
  83.         return accu >> LOGPLACE;
  84. }
  85. #endif
  86.  
  87. #ifdef __GNUC__
  88. PLACE PLACEmulsub(PLACE a, PLACE b, PLACE carry, PLACE *paccu) 
  89. #else
  90. PLACE PLACEmulsub(a, b, carry, paccu) 
  91.         PLACE a, b, carry, *paccu; 
  92. #endif
  93.     /* *paccu=*paccu-a*b-carry, return Uebertrag */
  94. {       register SDOUBLEPLACE saccu = 0;
  95.     register DOUBLEPLACE prod;
  96.         prod = a;
  97.         prod *= b;
  98.         prod += carry;
  99.         saccu = *paccu;
  100.     saccu-=(PLACE) prod;
  101.     prod>>=LOGRADIX;
  102.     *paccu=saccu;
  103.     saccu>>=LOGRADIX;
  104.     prod += (saccu & 1);
  105.         return prod;
  106. }
  107.  
  108. #ifndef __PARC__
  109. #ifdef __GNUC__
  110. PLACE PLACEdiv(PLACE h, PLACE l, PLACE n, PLACE *q)
  111. #else
  112. PLACE PLACEdiv(h, l, n, q)
  113.     PLACE h, l, n, *q;
  114. #endif
  115.     /* h*RADIX+l / n ergibt Quotient *q, return Rest */
  116.         /* Division mit Rest
  117.               Voraussetzung:     h < n                */
  118. {       register DOUBLEPLACE accu = 0;
  119.         accu = (h<<LOGPLACE) | l;
  120.         *q = accu / n;
  121.         return accu % n;
  122. }
  123. #endif
  124. #endif
  125.  
  126. /**************************************************************/
  127.  
  128. #ifdef USE_IF_IN_ADD_AND_SUB
  129.  
  130. PLACE PLACEadd(a, b, carry, sum)
  131.     PLACE a, b, carry, *sum;
  132.     /* *sum=a+b+carry, return Uebertrag */
  133. {    PLACE accu;
  134.         accu = a + b + carry;
  135.         *sum = accu;
  136.     if (accu < a)
  137.         return 1;
  138.     else
  139.         return 0;
  140. }
  141.  
  142. PLACE PLACEsub(a, b, carry, diff)
  143.         PLACE a, b, carry, *diff;
  144.     /* *diff=a-b-carry, return Uebertrag 0 oder 1 */
  145. {       PLACE accu;
  146.         accu = a-b-carry;
  147.         *diff = accu;
  148.     if (accu > a)
  149.         return 1;
  150.     else
  151.         return 0;
  152. }
  153.  
  154. #endif
  155.  
  156. #ifndef USE_SPARC_ASM
  157. #ifdef sparc
  158. #ifndef USE_DOUBLEPLACE
  159.  
  160. #define LPM1 (LOGPLACE-1)
  161.  
  162. PLACE PLACEdiv(h, l, n, q)
  163.     PLACE h, l, n, *q;
  164.     /* h*RADIX+l / n ergibt Quotient *q, return Rest */
  165.         /* Division mit Rest
  166.               Voraussetzung:     h < n                */
  167. {       register PLACE qd = 0, carry;
  168.     register int i;
  169.     for (i=0; i<LOGPLACE; i++) {
  170.         carry=h>>LPM1;
  171.         h = (h<<1) | (l>>LPM1);
  172.         l = l<<1;
  173.         qd<<=1;
  174.         if (carry || h>=n) {
  175.             qd+=1;
  176.             h-=n;
  177.     }    }
  178.     *q = qd;
  179.     return h;
  180. }
  181.  
  182. #endif
  183. #endif
  184. #endif
  185.  
  186. /***************************************************************/
  187.  
  188. #ifndef ATARI
  189. BOOLEAN veceq(a, b, count)
  190.         register PLACE *a, *b; 
  191.         register int count;
  192.         /* return a[count]==b[count]; */
  193. {       for ( ; count>0; count--)
  194.                 if (*a++ != *b++)
  195.                         return FALSE;
  196.         return TRUE;
  197. }
  198. #endif
  199.  
  200. #ifndef ATARI
  201. BOOLEAN vecgt(a, b, count)
  202.         register PLACE *a, *b; 
  203.         register int count;
  204.         /* return a[count]>b[count] lexikographisch */
  205. {       for (a+=count, b+=count; count>0; count--) {
  206.         register PLACE aa, bb;
  207.         aa=*--a;
  208.         bb=*--b;
  209.                 if (aa > bb)
  210.                         return TRUE;
  211.                 else if (aa < bb)
  212.                         return FALSE;
  213.     }
  214.         return FALSE;
  215. }
  216. #endif
  217.  
  218. #ifndef ATARI
  219. #ifndef __PARC__
  220. BOOLEAN vecsr1(u, l)
  221.     register PLACE * u;
  222.     register int l;
  223. /*    b=u[l]%2; u[l]/=2; return b; */
  224. {    register PLACE b, bold, c;
  225.     u=u + l;
  226.     bold=0;
  227.     while(l) {
  228.         b=*--u;
  229.         c=b>>1;
  230.         c|=(bold<<(LOGRADIX-1));
  231.         bold=b;
  232.         *u=c;
  233.         l--;
  234.     }
  235.     b&=1;
  236.     return (BOOLEAN) b;
  237. }        /* vecsr1 */
  238. #endif
  239. #endif
  240.  
  241. #ifndef __PARC__
  242. #ifndef ATARI
  243. void vecsri(u, l, i)
  244.     register PLACE * u;
  245.     register int l;
  246.     register int i;
  247. /*    b=u[l]%2^i; u[l]/=2^i;     i<LOGRADIX */
  248. {    register PLACE b, bold, c;
  249.     u=u + l;
  250.     bold=0;
  251.     while(l) {
  252.         b=*--u;
  253.         c=b>>i;
  254.         c|=(bold<<(LOGRADIX-i));
  255.         bold=b;
  256.         *u=c;
  257.         l--;
  258.     }
  259. }        /* vecsri */
  260. #endif
  261. #endif
  262.  
  263. /**************************************************************/
  264.  
  265. #ifndef USE_DOUBLEPLACE
  266.  
  267. int cvadd(sum, a, b, counta, countb)
  268.         register pPLACE sum, a, b; 
  269.         register int counta, countb;
  270.         /* sum[]=a[counta]+b[countb]; 
  271.        sum soll auch Uebertraege fassen */
  272. {       register PLACE carry=0;
  273.     register int countmax;
  274.     if (counta>countb) {
  275.         countmax=counta;
  276.         counta-=countb;
  277.             for ( ; countb>0; countb--)
  278.             carry=PLACEadd(*a++, *b++, carry, sum++);
  279.             for ( ; counta>0; counta--)
  280.             carry=PLACEadd(*a++, 0, carry, sum++);
  281.     } else {
  282.         countmax=countb;
  283.         countb-=counta;
  284.             for ( ; counta>0; counta--)
  285.             carry=PLACEadd(*a++, *b++, carry, sum++);
  286.             for ( ; countb>0; countb--)
  287.             carry=PLACEadd(0, *b++, carry, sum++);
  288.         }
  289.     *sum=carry;
  290.     if (carry)
  291.         return countmax+1;
  292.     else
  293.         return countmax;
  294. }    /* cvadd */
  295.  
  296. #ifndef USE_SPARC_ASM
  297. void cvecsubto(a, b, count)
  298.         register PLACE *a, *b; 
  299.         register int count;
  300.         /* a[]-=b[count]; a muss groesser oder gleich b sein */
  301. {       register PLACE carry=0;
  302.         for ( ; count>0; count--) {
  303.         carry=PLACEsub(*a, *b++, carry, a);
  304.         a++;
  305.     }
  306.         while (carry) {
  307.         carry=PLACEsub(*a, 0, carry, a);
  308.         a++;
  309.     }
  310. }        /* cvecsubto */
  311. #endif
  312.  
  313. int cvsub(diff, a, b, counta, countb)
  314.     register pPLACE diff, a, b;
  315.     register int counta, countb;
  316.     /* diff[]=a[counta]-b[countb]; a>=b */
  317. {       register PLACE carry=0;
  318.     register int l=counta;
  319.     counta-=countb;
  320.     for ( ; countb>0; countb--)
  321.         carry=PLACEsub(*a++, *b++, carry, diff++);
  322.     while (carry) {
  323.         carry=PLACEsub(*a++, 0, carry, diff++);
  324.         counta--;
  325.     }
  326.     for ( ; counta>0; counta--) {
  327.         *diff++=*a++;
  328.     }
  329.     diff--;
  330.     while ((l>0)&&(! *diff)) {
  331.         diff--;
  332.         l--;
  333.     }
  334.     return l;
  335. }        /* cvsub */
  336.  
  337. PLACE vecaddto(a, b, count)
  338.         register PLACE *a, *b; 
  339.         register int count;
  340.         /* a[count]+=b[count]; return carry; */
  341. {       register PLACE carry=0;
  342.         for ( ; count>0; count--) {
  343.         carry=PLACEadd(*a, *b++, carry, a);
  344.         a++;
  345.     }
  346.         return carry;
  347. }
  348.  
  349. PLACE vecsubto(a, b, count)
  350.         register PLACE *a, *b; 
  351.         register int count;
  352.         /* a[count]-=b[count]; return carry; 0 oder 1 */
  353. {       register PLACE carry=0;
  354.         for ( ; count>0; count--) {
  355.         carry=PLACEsub(*a, *b++, carry, a);
  356.         a++;
  357.     }
  358.         return (carry & 1);
  359. }
  360.  
  361. #ifdef __GNUC__
  362. PLACE vecdiv(PLACE *q, PLACE *a, PLACE d, int count)
  363. #else
  364. PLACE vecdiv(q, a, d, count)
  365.         register PLACE *q, *a;
  366.     register PLACE d;
  367.         register int count;
  368. #endif
  369.         /* q[count]=a[count]/d; return a[count]%d; */
  370. {       register PLACE carry=0;
  371.         for (q+=count, a+=count; count>0; count--)
  372.         carry=PLACEdiv(carry, *--a, d, --q);
  373.         return carry;
  374. }
  375.  
  376. #ifdef __GNUC__
  377. PLACE vecmul(PLACE *product, PLACE *a, PLACE m, int count)
  378. #else
  379. PLACE vecmul(product, a, m, count)
  380.         register PLACE *product, *a, m;
  381.         register int count;
  382. #endif
  383.         /* product[count]=m*a[count]; return carry; */
  384. {       register PLACE carry=0;
  385.         for ( ; count>0; count--)
  386.         carry=PLACEmul(*a++, m, carry, product++);
  387.         return carry;
  388. }        /* vecmul */
  389.  
  390. #ifndef USE_SPARC_ASM
  391. #ifdef __GNUC__
  392. PLACE vecmuladd(PLACE *paccu, PLACE *a, PLACE m, int count)
  393. #else
  394. PLACE vecmuladd(paccu, a, m, count)
  395.         register PLACE *paccu, *a, m; 
  396.         register int count;
  397. #endif
  398.         /* paccu[count] += m*a[count]; return carry; */
  399. {       register PLACE carry=0;
  400.         for ( ; count>0; count--) {
  401.          carry=PLACEmuladd(*a++, m, carry, paccu++);
  402.         }
  403.         return carry;
  404. }        /* vecmuladd */
  405. #endif
  406.  
  407. #ifdef __GNUC__
  408. PLACE vecmulsub(PLACE *paccu, PLACE *a, PLACE m, int count)
  409. #else
  410. PLACE vecmulsub(paccu, a, m, count)
  411.         register PLACE *paccu, *a, m;
  412.         register int count;
  413. #endif
  414.         /* paccu[count+1] -= m*a[count]; return carry; 
  415.         carry ist 0 oder 1 */
  416. {    register PLACE carry=0;
  417.         for ( ; count>0; count--)
  418.         carry=PLACEmulsub(*a++, m, carry, paccu++);
  419.     carry=PLACEsub(*paccu, carry, 0, paccu);
  420.         return carry;
  421. }
  422.  
  423. #endif
  424.